package sg.edu.nus.iss.jass.persistence;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import sg.edu.nus.iss.jass.datastore.BaseDAO;
import sg.edu.nus.iss.jass.datastore.exception.DataStoreException;
import sg.edu.nus.iss.jass.datastore.impl.Selector;
import sg.edu.nus.iss.jass.dto.JobAdvert;
import sg.edu.nus.iss.jass.dto.SearchCriteria;
import sg.edu.nus.iss.jass.dto.Skill;
import sg.edu.nus.iss.jass.util.Util;
/**
 * <h5>JobAdvertDAO to perform job advertisement data operation</h5>
 * This  abstract class is derived from BaseDAO to get/save the jobadvert object.
 * @author Iwan Sinardinata
 * 
 */
public class JobAdvertDAO extends BaseDAO {
	/**
	 *  Method to insert the job advertisement to the property file by the given newly created job advertisement.
	 * @param jobAdvert
	 *            JobAdvert jobAdvert.
	 */
	public void createJobAdvert(JobAdvert jobAdvert) throws DataStoreException {
		save(jobAdvert);
	}
	/**
	 *  Method to reads data from the property file based on Job Advert with unique identifier.
	 * @param jobAdvert
	 *            JobAdvert jobAdvert.
	 */
	public JobAdvert findJobAd(JobAdvert jobAdvert) throws DataStoreException {
		if (jobAdvert.getId() == null || "".equals(jobAdvert.getId())) {
			System.out.println("JobAdvert with no ID should not be passed as parameter for findJobAd operation");
			return null;
		}
		return findJobAd(jobAdvert.getId());
	}
	/**
	 *  Method to reads data from the property file based on unique identifier of Job Advert.
	 * @param jobAdvertID
	 *            String jobAdvertID.
	 */
	public JobAdvert findJobAd(String jobAdvertID) throws DataStoreException {
		return selectById(JobAdvert.class, jobAdvertID);
	}
	/**
	 *  Method to updates the job advertisement to the property file by the given updated job advertisement.
	 * @param jobAdvert
	 *            JobAdvert jobAdvert.
	 */
	public void updateJobAdvert(JobAdvert jobAdvert) throws DataStoreException {
		save(jobAdvert);
	}
	/**
	 *  Method to delete the jobadvert record by updating the status in property file.
	 * @param updateJobAdverts
	 *            List<JobAdvert> jobAdvertList.
	 */
	public void updateJobAdverts(List<JobAdvert> jobAdvertList) throws DataStoreException {
		saveObjects(jobAdvertList);
	}
	/**
	 *  Method to search for jobadvert in file based on one or more search criteria.
	 * @param searchCriteria
	 *            SearchCriteria searchCriteria.
	 */
	public List<JobAdvert> findJobAd(SearchCriteria searchCriteria) throws DataStoreException{
		if(searchCriteria != null) {
			Selector sel = new Selector();
			
			sel.eq("status", true);
			
			if(searchCriteria.getCompanyId() != null){
				sel.eq("companyId", searchCriteria.getCompanyId());
			}
			if(searchCriteria.getSalaryRange() != null){
				String range[] = searchCriteria.getSalaryRange().split("-");
				if(range.length == 1){
					float min = Float.parseFloat(range[0]);
					sel.ge("minSalary", min);
					sel.le("maxSalary", min);
				} else if(range.length == 2){
					float min = Float.parseFloat(range[0]);
					float max = Float.parseFloat(range[1]);
					sel.ge("minSalary", min);
					sel.le("maxSalary", max);
				}
			}
			if(searchCriteria.getLocationId() != null){
				sel.eq("geographicalLocationId", searchCriteria.getLocationId());
			}
			
			
			
			if(!Util.isEmpty(searchCriteria.getNoOfDays())){
				Calendar cur = Calendar.getInstance();
				cur.add(Calendar.DAY_OF_MONTH, (-1)*Integer.parseInt(searchCriteria.getNoOfDays()));
				sel.ge("startDate", Util.getDateFromString(Util.getStringFromdate(cur.getTime())));
			}
			
			if(!Util.isEmpty(searchCriteria.getKeyword())){
				sel.like("description", searchCriteria.getKeyword());
			}
			
			List<JobAdvert> jobs = select(JobAdvert.class, sel);
			List<JobAdvert> returnJobs = new ArrayList<JobAdvert>();
			if(!Util.isEmpty(searchCriteria.getSkillIds()) && !Util.isEmpty(jobs)){
				boolean containsSkill = false;
				for(JobAdvert job:jobs){
					containsSkill = false;
					List<Skill> skills = (new SkillDAO()).getSkillByIds(job.getIdList(job.getSkillIds()));
					for(Skill skill:skills){
						for(String id:searchCriteria.getSkillIds()){
							if(id.equals(skill.getSkillRefId())){
								containsSkill = true;
								returnJobs.add(job);
								break;
							}
						}
						if(containsSkill) {
							break;
						}
					}
					
				}
				return returnJobs;
			} else {
				return jobs;
			}
		}
		return selectAll(JobAdvert.class);
	}

}
